{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "# भाग 2: Syft Keras सह सुरक्षित मॉडेल सर्व्हिंग\n",
    "\n",
    "आता आपल्याकडे सामान्य Keras असलेले एक प्रशिक्षित मॉडेल आहे, आपण काही खाजगी अंदाज देण्यासाठी तयार आहात. हे आपण Syft Keras वापरुन करू शकतो.\n",
    "\n",
    "हे मॉडेल सुरक्षित आणि सेवा देण्यासाठी, आपल्याला तीन TFEWorkers (सर्व्हर) आवश्यक असतील. याचे कारण असे की हुड अंतर्गत TF एनक्रिप्टेड केलेले [मल्टी-पार्टी कंप्यूटेशन (MPC)](https://en.wikipedia.org/wiki/Secure) नावाचे एनक्रिप्शन तंत्र वापरते. मॉडेल वजनाची आणि इनपुट डेटाची शेअर्समध्ये विभागणी करणे, त्यानंतर प्रत्येक सर्व्हरला एक हिस्सा वेगवेगळ्या सर्व्हर्सवर पाठविण्याची कल्पना आहे. मुख्य गुणधर्म अशी आहे की जर आपण एका सर्व्हरवरील शेअर्सकडे पाहिले तर ते मूळ मूल्याबद्दल काहीही सांगत नाही (इनपुट डेटा किंवा मॉडेल वजन).\n",
    "\n",
    "आम्ही मागील नोटबुक प्रमाणेच एक Syft Keras मॉडेल परिभाषित करू. तथापि, एक युक्ती आहेः हे मॉडेल स्थापित करण्यापूर्वी, आम्ही `hook = sy.KerasHook (tf.keras)` चालवू. हे केरास अनुक्रमिक वर्गामध्ये तीन महत्त्वाच्या नवीन पद्धती जोडेल:\n",
    "- `share`: गुपित सामायिकरणातून त्याचे मॉडेल सुरक्षित करेल; डीफॉल्टनुसार, tf  एन्क्रिप्टेडकडून SecureNN प्रोटोकॉल वापरुन प्रत्येक तीन TFEWorkers प्रत्येकात ते गुप्तपणे आपले मॉडेल सामायिक करेल. सर्वात महत्त्वाचे म्हणजे, ते एन्क्रिप्टेड डेटावर अंदाज करण्याची क्षमता जोडेल.\n",
    "- `serve`: हे कार्य एक सर्व्हिंग रांग लाँच करेल, जेणेकरून TFEWorkers  सुरक्षित मॉडेलवर बाह्य ग्राहकांकडील अंदाज विनंत्या स्वीकारू शकतील.\n",
    "- `shutdown_workers`: एकदा आपण खाजगी अंदाज दिल्यास आपण हे कार्य चालवून आपले मॉडेल बंद करू शकता. आपण प्रत्येक कामगार व्यक्तिचलितपणे व्यवस्थापित करणे निवडले असल्यास ते आपल्याला सर्व्हर प्रक्रिया बंद करण्यासाठी व्यक्तिचलितपणे निर्देशित करते.\n",
    "\n",
    "आपण MPC अधिक जाणून घेऊ इच्छित असल्यास आपण हा उत्कृष्ट [ब्लॉग](https://mortendahl.github.io/2017/04/17/pStreet-deep-learning-with-mpc/) वाचू शकता."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "अनुवादक/संपादक:\n",
    "- Krunal Kshirsagar - Twitter: [@krunal_wrote](https://twitter.com/krunal_wrote) - Github: [@Noob-can-Compile](https://github.com/Noob-can-Compile)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from tensorflow.keras import Sequential\n",
    "from tensorflow.keras.layers import AveragePooling2D, Conv2D, Dense, Activation, Flatten, ReLU, Activation\n",
    "\n",
    "import syft as sy\n",
    "hook = sy.KerasHook(tf.keras)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "## मॉडेल"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "आपण पाहू शकता की आम्ही `batch_input_shape` प्रदान केल्याशिवाय आम्ही पूर्वीप्रमाणेच अगदी जवळजवळ समान मॉडेलची व्याख्या केली आहे. हे TF एन्क्रिप्टेडला पूर्वनिर्धारित टेन्सर आकारांद्वारे सुरक्षित संगणनास अधिक अनुकूलित करण्यास अनुमती देते. या MNIST डेमोसाठी आम्ही इनपुट डेटा पाठवू (1, 28, 28, 1). आम्ही हे ऑपरेशन MPC वापरून करण्यासाठी क्लिष्ट आहे कारण softmax ऐवजी logit परत, आणि आम्ही अंदाज विनंत्या सेवा करण्यासाठी आपल्याला त्याची आवश्यकता नाही."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "num_classes = 10\n",
    "input_shape = (1, 28, 28, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /usr/local/miniconda3/envs/syft/lib/python3.6/site-packages/tensorflow/python/ops/resource_variable_ops.py:435: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Colocations handled automatically by placer.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:tensorflow:From /usr/local/miniconda3/envs/syft/lib/python3.6/site-packages/tensorflow/python/ops/resource_variable_ops.py:435: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\n",
      "Instructions for updating:\n",
      "Colocations handled automatically by placer.\n"
     ]
    }
   ],
   "source": [
    "model = Sequential()\n",
    "\n",
    "model.add(Conv2D(10, (3, 3), batch_input_shape=input_shape))\n",
    "model.add(AveragePooling2D((2, 2)))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Conv2D(32, (3, 3)))\n",
    "model.add(AveragePooling2D((2, 2)))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Conv2D(64, (3, 3)))\n",
    "model.add(AveragePooling2D((2, 2)))\n",
    "model.add(Activation('relu'))\n",
    "model.add(Flatten())\n",
    "model.add(Dense(num_classes, name=\"logit\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "### पूर्व-प्रशिक्षित वजन लोड करा"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "`load_weights` सह आपण आपल्या मॉडेलचे प्रशिक्षण घेतल्यानंतर आपण जतन केलेले वजन(weights) सहजपणे लोड करू शकता."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "pre_trained_weights = 'short-conv-mnist.h5'\n",
    "model.load_weights(pre_trained_weights)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "### कामगार लाँच करा"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "आता खाजगी अंदाज घेण्यासाठी TF Encrypted कडून आवश्यक TFEWorkers (`alice`,` bob`, और `carol`) तयार करूया. प्रत्येक TFEWorker साठी, आपल्याला फक्त एक होस्ट निर्दिष्ट करावा लागेल. त्यानंतर आम्ही या कामगारांना क्लस्टरमध्ये एकत्र करतो.\n",
    "\n",
    "हे कामगार [TensorFlow सर्व्हर](https://www.tensorflow.org/api_docs/python/tf/distribute/Server) चालवतात, जे आपण एकतर व्यक्तिचलितरित्या व्यवस्थापित करू शकता (`AUTO = False`) किंवा कामगारांना आपल्यासाठी व्यवस्थापित करण्यास सांगू शकता (`AUTO = True`). त्या व्यक्तिचलितरित्या व्यवस्थापित करणे निवडल्यास, आपल्याला खाली असलेल्या `cluster.start()` वर कॉल केल्यानंतर प्रत्येक कामगारांच्या होस्ट डिव्हाइसवर टर्मिनल आदेश चालविण्यास सूचित केले जाईल. जर सर्व कामगार एका डिव्हाइसवर (उदा. `localhost`) वर होस्ट केलेले असतील तर आपण Syft आपोआप कामगारांचे TensorFlow सर्व्हर व्यवस्थापित करू शकता."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tf_encrypted:If not done already, please launch the following command in a terminal on host localhost:4000: 'python -m tf_encrypted.player --config /var/folders/mh/7hh_sz1d3532_k9w4kcmnt8c0000gn/T/tfe.config server0'\n",
      "This can be done automatically in a local subprocess by setting `auto_managed=True` when instantiating a TFEWorker.\n",
      "\n",
      "INFO:tf_encrypted:If not done already, please launch the following command in a terminal on host localhost:4001: 'python -m tf_encrypted.player --config /var/folders/mh/7hh_sz1d3532_k9w4kcmnt8c0000gn/T/tfe.config server1'\n",
      "This can be done automatically in a local subprocess by setting `auto_managed=True` when instantiating a TFEWorker.\n",
      "\n",
      "INFO:tf_encrypted:If not done already, please launch the following command in a terminal on host localhost:4002: 'python -m tf_encrypted.player --config /var/folders/mh/7hh_sz1d3532_k9w4kcmnt8c0000gn/T/tfe.config server2'\n",
      "This can be done automatically in a local subprocess by setting `auto_managed=True` when instantiating a TFEWorker.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "AUTO = False\n",
    "\n",
    "alice = sy.TFEWorker(host='localhost:4000', auto_managed=AUTO)\n",
    "bob = sy.TFEWorker(host='localhost:4001', auto_managed=AUTO)\n",
    "carol = sy.TFEWorker(host='localhost:4002', auto_managed=AUTO)\n",
    "\n",
    "cluster = sy.TFECluster(alice, bob, carol)\n",
    "cluster.start()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "### वजन सामायिक करुन मॉडेलला सुरक्षित करा"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "`sy.KerasHook (tf.keras)` चे आभार मानून आपण आपल्या मॉडेलला TF एन्क्रिप्टेड Keras मॉडेलमध्ये रूपांतरित करण्यासाठी `share` पद्धत कॉल करू शकता.\n",
    "\n",
    "जर आपल्याला सर्व्हर व्यक्तिचलितपणे व्यवस्थापित करण्यास सांगितले असेल तर ते सर्व लाँच होईपर्यंत हे चरण पूर्ण होणार नाही. लक्षात ठेवा की आपली फायरवॉल पायथनला येणारे कनेक्शन स्वीकारण्यास विचारू शक्तो."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "lang": "en",
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tf_encrypted:Starting session on target 'grpc://localhost:4000' using config graph_options {\n",
      "}\n",
      "\n"
     ]
    }
   ],
   "source": [
    "model.share(cluster)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### मॉडेल सर्व्ह करावे"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "परिपूर्ण! आता `model.serve` कॉल करून, आपले मॉडेल काही खाजगी अंदाज देण्यासाठी सज्ज आहे. आपण मॉडेलद्वारे दिल्या गेलेल्या पूर्वानुमान विनंत्यांच्या संख्येवर मर्यादा सेट करण्यासाठी `num_requests` सेट करू शकता; निर्दिष्ट न केल्यास मॉडेल व्यत्यय येईपर्यंत दिला जाईल."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Served encrypted prediction 1 to client.\n",
      "Served encrypted prediction 2 to client.\n",
      "Served encrypted prediction 3 to client.\n"
     ]
    }
   ],
   "source": [
    "model.serve(num_requests=3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "आपण काही खाजगी अंदाज मागण्यासाठी पार्ट 13 सी नोटबुकवर जाण्यास तयार आहात."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "### क्लिनअप!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "lang": "hi"
   },
   "source": [
    "एकदा आपली विनंती मर्यादा झाली की, मॉडेल्स यापुढे सर्व्हिसिंग विनंत्यांसाठी उपलब्ध नसतील, परंतु तरीही वरील तीन कामगारांमध्ये ते सामायिक आहे. आपण खाली सेल चालवून कामगारांना मारू शकता.\n",
    "\n",
    "**अभिनंदन** भाग 13 बी पूर्ण केल्याबद्दल: सिफ्ट केरास आणि टीएफईसह सुरक्षित वर्गीकरण!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:tf_encrypted:Please terminate the process on host 'localhost:4000'.\n",
      "INFO:tf_encrypted:Please terminate the process on host 'localhost:4001'.\n",
      "INFO:tf_encrypted:Please terminate the process on host 'localhost:4002'.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Process ID 12470 has been killed.\n",
      "Process ID 12474 has been killed.\n",
      "Process ID 12464 has been killed.\n"
     ]
    }
   ],
   "source": [
    "model.stop()\n",
    "cluster.stop()\n",
    "\n",
    "if not AUTO:\n",
    "    process_ids = !ps aux | grep '[p]ython -m tf_encrypted.player --config' | awk '{print $2}'\n",
    "    for process_id in process_ids:\n",
    "        !kill {process_id}\n",
    "        print(\"Process ID {id} has been killed.\".format(id=process_id))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3-final"
  },
  "nbTranslate": {
   "displayLangs": [
    "hi"
   ],
   "hotkey": "alt-t",
   "langInMainMenu": true,
   "sourceLang": "en",
   "targetLang": "hi",
   "useGoogleTranslate": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}